export class ClassEvents {
  constructor() {
    // 用来存储自定义事件的哈希表
    this.__events = {}
  }

  /**
   * 绑定自定义事件
   * @param type 事件名称
   * @param callback 回调函数
   * @returns {ClassEvents}
   */
  $on(type, callback) {
    // 为了按类查找方便和节省空间
    // 将同一类型事件放到一个数组中
    // 这里的数组是队列， 遵循先进先出
    // 即新绑定的事件先触发
    const fns = (this.__events[type] = this.__events[type] || [])
    if (fns.indexOf(callback) === -1) {
      fns.push(callback)
    }
    return this
  }

  /**
   * 触发自定义事件
   * @param type 事件名称
   * @param data 数据
   * @returns {ClassEvents}
   */
  $emit(type, data) {
    const fns = this.__events[type]
    if (Array.isArray(fns)) {
      fns.forEach((fn) => {
        fn(data)
      })
    }
    return this
  }

  /**
   * 解绑 自定义事件
   * @param type 事件名称
   * @param callback 之前绑定的回调函数，如果不传该值则解绑所有同名事件
   * @returns {ClassEvents}
   */
  $off(type, callback) {
    const fns = this.__events[type]
    if (Array.isArray(fns)) {
      if (callback) {
        const index = fns.indexOf(callback)
        if (index !== -1) {
          fns.splice(index, 1)
        }
      } else {
        // 全部清空
        fns.length = 0
      }
    }
    return this
  }
}
